from django.db import models
from django.utils import timezone
from django.urls import reverse
from django.contrib.auth.models import User

def in_upload_path(instance, filename):
    """ Function to return upload path for test case input file"""
    return "/".join(["testcases", str(instance.problem.id)]) + ".in"


def out_upload_path(instance, filename):
    """ Function to return upload path for test case output file"""
    return "/".join(["testcases", str(instance.problem.id)]) + ".out"

class Category(models.Model):
	name = models.CharField(max_length=100)
	class Meta:
		verbose_name = '文章分类'
		verbose_name_plural = verbose_name
	def __str__(self):
		return self.name

class Tag(models.Model):
	name = models.CharField(max_length=100)
	class Meta:
		verbose_name = '文章标签'
		verbose_name_plural = verbose_name
	def __str__(self):
		return self.name

class Post(models.Model):
	#标题 正文
	title = models.CharField('标题',max_length=100)
	body = models.TextField('正文')
	#创建时间 最后一次修改时间
	created_time = models.DateTimeField('创建时间',default=timezone.now)
	modeified_time = models.DateTimeField('修改时间',default=timezone.now)
	#摘要
	excerpt = models.CharField('摘要',max_length=200,blank=True)
	#分类 标签
	category = models.ForeignKey(Category,verbose_name='分类',on_delete=models.CASCADE)
	tags = models.ManyToManyField(Tag,verbose_name='标签',blank=True)
	#作者 User 来自 django.contrib.auth.models
	author = models.ForeignKey('Coder', verbose_name='作者',null = True,on_delete=models.CASCADE)
	def save(self, *args ,**kwargs):
		self.modified_time = timezone.now()
		super().save(*args, **kwargs)
	class Meta:
		verbose_name='文章'
		verbose_name_plural = verbose_name
	def __str__(self):
		return self.title
	def get_absolute_url(self):
		return reverse('machine:detail', kwargs={'pk': self.pk})

# Model for users
class Coder(models.Model):
    user = models.OneToOneField(User,on_delete=models.CASCADE)
    
    #photo = models.URLField(max_length=256,blank=True)
    avatar = models.ImageField(upload_to='avatar', default='', verbose_name='头像')

    link = models.URLField()
    score = models.DecimalField(default = 0, decimal_places = 3, max_digits = 100)
    rank = models.IntegerField(default = -1)
    problems_tried = models.ForeignKey('Problem', null = True, related_name = "problems_tried",on_delete=models.CASCADE)
    problems_ac = models.ForeignKey('Problem', null = True, related_name = "problems_ac",on_delete=models.CASCADE)

    def __str__(self):
        #return str(self.user)
        return str(self.user.username)
    
    def get_avatar_url(self):
        return MEDIA_ADDR + str(self.avatar)

#try to update users
class CodeUsers(models.Model):
    name = models.CharField('用户',max_length=128,unique=True)
    password = models.CharField('密码',max_length=256)
    email = models.EmailField('邮箱',unique=True)
    c_time = models.DateTimeField('创建时间',auto_now_add=True)

    def __str__(self):
        return self.name

    class Meta:
        ordering = ['c_time']
        verbose_name = '用户'
        verbose_name_plural = '用户'


# Model for the Problems to be uploaded on the judge
class Problem(models.Model):
    # Problem name (example: life, the universe and everything)
    name = models.CharField('问题标题',max_length=255)
    # Problem code (example: TEST)
    code = models.CharField('问题路径(别名)',max_length=20, unique = True)
    # Problem link (example: poj.com/problems/TEST)
    link = models.URLField('问题链接(对应路径)')
    # Problem statement
    statement = models.TextField('问题描述')

    num_submissions = models.IntegerField(default = 0) # number of submissions
    num_ac = models.IntegerField(default = 0)     # number of accepted submissions
    num_wa = models.IntegerField(default = 0)          # number of wrong answers
    num_re = models.IntegerField(default = 0)          # number of runtime errors
    num_tle = models.IntegerField(default = 0)         # number of tles
    num_ce = models.IntegerField(default = 0)
    date_added = models.DateTimeField(auto_now_add = True) # When added
    time_limit = models.IntegerField(default=1)         # Time Limit
    source = models.CharField(max_length=255)
    num_tests = models.IntegerField(default = 1)

    #author = models.ForeignKey('Coder', null = True,on_delete=models.CASCADE)
    class Meta:
    	   verbose_name = '问题集'
    	   verbose_name_plural = verbose_name
    def __str__(self):
        return str(self.code)


# Model for Test Cases
class TestCase(models.Model):
    problem = models.ForeignKey(Problem,verbose_name='问题(别名)',on_delete=models.CASCADE)
    input_file = models.FileField('输入文件',upload_to=in_upload_path)
    output_file = models.FileField('输出文件',upload_to=out_upload_path)
    class Meta:
        verbose_name = '测试数据'
        verbose_name_plural = verbose_name
    def __str__(self):
        return str(self.problem)

LANGUAGES = (
                ("C", "GNU C"),
                ("CPP", "GNU C++"),
            )


# Model for problem submissions
class Submission(models.Model):
    STATUSES = (
	                ("NT", "Not tested"),
	                ("CE", "Compile Error"),
	                ("TL", "Time Limit Exceeded"),
	                ("RE", "Runtime Error"),
	                ("AC", "Accepted")
                )
    submitter = models.ForeignKey(Coder, null = True,on_delete=models.CASCADE)
    problem = models.ForeignKey(Problem, default = None, null = True,on_delete=models.CASCADE)
    status = models.CharField(max_length = 2, default = "NT", choices = STATUSES)
    lang = models.CharField(max_length = 4, default = "C", choices = LANGUAGES)
    code = models.TextField(default="")
    created = models.DateTimeField(auto_now_add=True)
    private = models.BooleanField(default = True)
    class Meta:
        verbose_name = '提交结果'
        verbose_name_plural = verbose_name
